{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# StackingCVClassifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An ensemble-learning meta-classifier for stacking using cross-validation to prepare the inputs for the level-2 classifier to prevent overfitting."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> from mlxtend.classifier import StackingCVClassifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Overview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Stacking is an ensemble learning technique to combine multiple classification models via a meta-classifier. The `StackingCVClassifier` extends the standard stacking algorithm (implemented as [`StackingClassifier`](StackingClassifier.md)) using cross-validation to prepare the input data for the level-2 classifier. \n",
    "\n",
    "In the standard stacking procedure, the first-level classifiers are fit to the same training set that is used prepare the inputs for the second-level classifier, which may lead to overfitting. The `StackingCVClassifier`, however, uses the concept of cross-validation: the dataset is split into *k* folds, and in *k* successive rounds, *k-1* folds are used to fit the first level classifier; in each round, the first-level classifiers are then applied to the remaining 1 subset that was not used for model fitting in each iteration. The resulting predictions are then stacked and provided -- as input data -- to the second-level classifier. After the training of the `StackingCVClassifier`, the first-level classifiers are fit to the entire dataset as illustrated in the figure below."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](./StackingCVClassifier_files/stacking_cv_classification_overview.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "More formally, the Stacking Cross-Validation algorithm can be summarized as follows (source: [1]):\n",
    "    \n",
    "![](./StackingCVClassifier_files/stacking_cv_algorithm.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### References\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [1] Tang, J., S. Alelyani, and H. Liu. \"[Data Classification: Algorithms and Applications.](https://books.google.com/books?id=nwQZCwAAQBAJ&lpg=PA500&dq=stacking%20classifier%20subsets&pg=PA499#v=onepage&q&f=false)\" Data Mining and Knowledge Discovery Series, CRC Press (2015): pp. 498-500.\n",
    "- [2] Wolpert, David H. \"[Stacked generalization.](http://www.sciencedirect.com/science/article/pii/S0893608005800231)\" Neural networks 5.2 (1992): 241-259."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 1 - Simple Stacking CV Classification"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "\n",
    "iris = datasets.load_iris()\n",
    "X, y = iris.data[:, 1:3], iris.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3-fold cross validation:\n",
      "\n",
      "Accuracy: 0.91 (+/- 0.01) [KNN]\n",
      "Accuracy: 0.90 (+/- 0.03) [Random Forest]\n",
      "Accuracy: 0.92 (+/- 0.03) [Naive Bayes]\n",
      "Accuracy: 0.91 (+/- 0.01) [StackingClassifier]\n"
     ]
    }
   ],
   "source": [
    "from sklearn import model_selection\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.naive_bayes import GaussianNB \n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from mlxtend.classifier import StackingCVClassifier\n",
    "import numpy as np\n",
    "import warnings\n",
    "\n",
    "warnings.simplefilter('ignore')\n",
    "\n",
    "RANDOM_SEED = 42\n",
    "\n",
    "clf1 = KNeighborsClassifier(n_neighbors=1)\n",
    "clf2 = RandomForestClassifier(random_state=RANDOM_SEED)\n",
    "clf3 = GaussianNB()\n",
    "lr = LogisticRegression()\n",
    "\n",
    "# Starting from v0.16.0, StackingCVRegressor supports\n",
    "# `random_state` to get deterministic result.\n",
    "sclf = StackingCVClassifier(classifiers=[clf1, clf2, clf3],\n",
    "                            meta_classifier=lr,\n",
    "                            random_state=RANDOM_SEED)\n",
    "\n",
    "print('3-fold cross validation:\\n')\n",
    "\n",
    "for clf, label in zip([clf1, clf2, clf3, sclf], \n",
    "                      ['KNN', \n",
    "                       'Random Forest', \n",
    "                       'Naive Bayes',\n",
    "                       'StackingClassifier']):\n",
    "\n",
    "    scores = model_selection.cross_val_score(clf, X, y, \n",
    "                                              cv=3, scoring='accuracy')\n",
    "    print(\"Accuracy: %0.2f (+/- %0.2f) [%s]\" \n",
    "          % (scores.mean(), scores.std(), label))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from mlxtend.plotting import plot_decision_regions\n",
    "import matplotlib.gridspec as gridspec\n",
    "import itertools\n",
    "\n",
    "gs = gridspec.GridSpec(2, 2)\n",
    "\n",
    "fig = plt.figure(figsize=(10,8))\n",
    "\n",
    "for clf, lab, grd in zip([clf1, clf2, clf3, sclf], \n",
    "                         ['KNN', \n",
    "                          'Random Forest', \n",
    "                          'Naive Bayes',\n",
    "                          'StackingCVClassifier'],\n",
    "                          itertools.product([0, 1], repeat=2)):\n",
    "\n",
    "    clf.fit(X, y)\n",
    "    ax = plt.subplot(gs[grd[0], grd[1]])\n",
    "    fig = plot_decision_regions(X=X, y=y, clf=clf)\n",
    "    plt.title(lab)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 2 - Using Probabilities as Meta-Features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively, the class-probabilities of the first-level classifiers can be used to train the meta-classifier (2nd-level classifier) by setting `use_probas=True`. For example, in a 3-class setting with 2 level-1 classifiers, these classifiers may make the following \"probability\" predictions for 1 training sample:\n",
    "\n",
    "- classifier 1: [0.2, 0.5, 0.3]\n",
    "- classifier 2: [0.3, 0.4, 0.4]\n",
    "\n",
    "This results in *k* features, where *k* = [n_classes * n_classifiers], by stacking these level-1 probabilities:\n",
    "\n",
    "- [0.2, 0.5, 0.3, 0.3, 0.4, 0.4]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3-fold cross validation:\n",
      "\n",
      "Accuracy: 0.91 (+/- 0.01) [KNN]\n",
      "Accuracy: 0.93 (+/- 0.05) [Random Forest]\n",
      "Accuracy: 0.92 (+/- 0.03) [Naive Bayes]\n",
      "Accuracy: 0.95 (+/- 0.04) [StackingClassifier]\n"
     ]
    }
   ],
   "source": [
    "clf1 = KNeighborsClassifier(n_neighbors=1)\n",
    "clf2 = RandomForestClassifier(random_state=1)\n",
    "clf3 = GaussianNB()\n",
    "lr = LogisticRegression()\n",
    "\n",
    "sclf = StackingCVClassifier(classifiers=[clf1, clf2, clf3],\n",
    "                            use_probas=True,\n",
    "                            meta_classifier=lr,\n",
    "                            random_state=42)\n",
    "\n",
    "print('3-fold cross validation:\\n')\n",
    "\n",
    "for clf, label in zip([clf1, clf2, clf3, sclf], \n",
    "                      ['KNN', \n",
    "                       'Random Forest', \n",
    "                       'Naive Bayes',\n",
    "                       'StackingClassifier']):\n",
    "\n",
    "    scores = model_selection.cross_val_score(clf, X, y, \n",
    "                                              cv=3, scoring='accuracy')\n",
    "    print(\"Accuracy: %0.2f (+/- %0.2f) [%s]\" \n",
    "          % (scores.mean(), scores.std(), label))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 3 - Stacked CV Classification and GridSearch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The stack allows tuning hyper parameters of the base and meta models! A full list of tunable parameters can be obtained via `estimator.get_params().keys()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.673 +/- 0.01 {'kneighborsclassifier__n_neighbors': 1, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 10}\n",
      "0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 1, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 50}\n",
      "0.933 +/- 0.02 {'kneighborsclassifier__n_neighbors': 1, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "0.920 +/- 0.02 {'kneighborsclassifier__n_neighbors': 1, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 50}\n",
      "0.673 +/- 0.01 {'kneighborsclassifier__n_neighbors': 5, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 10}\n",
      "0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 5, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 50}\n",
      "0.940 +/- 0.02 {'kneighborsclassifier__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "0.927 +/- 0.02 {'kneighborsclassifier__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 50}\n",
      "Best parameters: {'kneighborsclassifier__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "Accuracy: 0.94\n"
     ]
    }
   ],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.naive_bayes import GaussianNB \n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from mlxtend.classifier import StackingCVClassifier\n",
    "\n",
    "# Initializing models\n",
    "\n",
    "clf1 = KNeighborsClassifier(n_neighbors=1)\n",
    "clf2 = RandomForestClassifier(random_state=RANDOM_SEED)\n",
    "clf3 = GaussianNB()\n",
    "lr = LogisticRegression()\n",
    "\n",
    "sclf = StackingCVClassifier(classifiers=[clf1, clf2, clf3], \n",
    "                            meta_classifier=lr,\n",
    "                            random_state=42)\n",
    "\n",
    "params = {'kneighborsclassifier__n_neighbors': [1, 5],\n",
    "          'randomforestclassifier__n_estimators': [10, 50],\n",
    "          'meta_classifier__C': [0.1, 10.0]}\n",
    "\n",
    "grid = GridSearchCV(estimator=sclf, \n",
    "                    param_grid=params, \n",
    "                    cv=5,\n",
    "                    refit=True)\n",
    "grid.fit(X, y)\n",
    "\n",
    "cv_keys = ('mean_test_score', 'std_test_score', 'params')\n",
    "\n",
    "for r, _ in enumerate(grid.cv_results_['mean_test_score']):\n",
    "    print(\"%0.3f +/- %0.2f %r\"\n",
    "          % (grid.cv_results_[cv_keys[0]][r],\n",
    "             grid.cv_results_[cv_keys[1]][r] / 2.0,\n",
    "             grid.cv_results_[cv_keys[2]][r]))\n",
    "\n",
    "print('Best parameters: %s' % grid.best_params_)\n",
    "print('Accuracy: %.2f' % grid.best_score_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In case we are planning to use a regression algorithm multiple times, all we need to do is to add an additional number suffix in the parameter grid as shown below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.673 +/- 0.01 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 10}\n",
      "0.667 +/- 0.00 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 50}\n",
      "0.947 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "0.920 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 50}\n",
      "0.673 +/- 0.01 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 10}\n",
      "0.667 +/- 0.00 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 50}\n",
      "0.960 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "0.933 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 50}\n",
      "0.673 +/- 0.01 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 10}\n",
      "0.667 +/- 0.00 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 50}\n",
      "0.960 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "0.933 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 1, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 50}\n",
      "0.673 +/- 0.01 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 10}\n",
      "0.667 +/- 0.00 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 0.1, 'randomforestclassifier__n_estimators': 50}\n",
      "0.953 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "0.927 +/- 0.02 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 50}\n",
      "Best parameters: {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 5, 'meta_classifier__C': 10.0, 'randomforestclassifier__n_estimators': 10}\n",
      "Accuracy: 0.96\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "# Initializing models\n",
    "\n",
    "clf1 = KNeighborsClassifier(n_neighbors=1)\n",
    "clf2 = RandomForestClassifier(random_state=RANDOM_SEED)\n",
    "clf3 = GaussianNB()\n",
    "lr = LogisticRegression()\n",
    "\n",
    "sclf = StackingCVClassifier(classifiers=[clf1, clf1, clf2, clf3], \n",
    "                            meta_classifier=lr,\n",
    "                            random_state=RANDOM_SEED)\n",
    "\n",
    "params = {'kneighborsclassifier-1__n_neighbors': [1, 5],\n",
    "          'kneighborsclassifier-2__n_neighbors': [1, 5],\n",
    "          'randomforestclassifier__n_estimators': [10, 50],\n",
    "          'meta_classifier__C': [0.1, 10.0]}\n",
    "\n",
    "grid = GridSearchCV(estimator=sclf, \n",
    "                    param_grid=params, \n",
    "                    cv=5,\n",
    "                    refit=True)\n",
    "grid.fit(X, y)\n",
    "\n",
    "cv_keys = ('mean_test_score', 'std_test_score', 'params')\n",
    "\n",
    "for r, _ in enumerate(grid.cv_results_['mean_test_score']):\n",
    "    print(\"%0.3f +/- %0.2f %r\"\n",
    "          % (grid.cv_results_[cv_keys[0]][r],\n",
    "             grid.cv_results_[cv_keys[1]][r] / 2.0,\n",
    "             grid.cv_results_[cv_keys[2]][r]))\n",
    "\n",
    "print('Best parameters: %s' % grid.best_params_)\n",
    "print('Accuracy: %.2f' % grid.best_score_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**\n",
    "\n",
    "The `StackingClassifier` also enables grid search over the `classifiers` argument. When there are level-mixed hyperparameters, GridSearchCV will try to replace hyperparameters in a top-down order, i.e., classifers -> single base classifier -> classifier hyperparameter. For instance,  given a hyperparameter grid such as\n",
    "\n",
    "    params = {'randomforestclassifier__n_estimators': [1, 100],\n",
    "    'classifiers': [(clf1, clf1, clf1), (clf2, clf3)]}\n",
    "    \n",
    "it will first use the instance settings of either (clf1, clf1, clf1) or (clf2, clf3). Then it will replace the `'n_estimators'` settings for a matching classifier based on `'randomforestclassifier__n_estimators': [1, 100]`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 4 - Stacking of Classifiers that Operate on Different Feature Subsets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The different level-1 classifiers can be fit to different subsets of features in the training dataset. The following example illustrates how this can be done on a technical level using scikit-learn pipelines and the `ColumnSelector`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StackingCVClassifier(classifiers=[Pipeline(memory=None,\n",
       "     steps=[('columnselector', ColumnSelector(cols=(0, 2), drop_axis=False)), ('logisticregression', LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='warn',\n",
       "          n_jobs=None,...nalty='l2', random_state=None, solver='warn',\n",
       "          tol=0.0001, verbose=0, warm_start=False))])],\n",
       "           cv=2, drop_last_proba=False,\n",
       "           meta_classifier=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='warn',\n",
       "          n_jobs=None, penalty='l2', random_state=None, solver='warn',\n",
       "          tol=0.0001, verbose=0, warm_start=False),\n",
       "           n_jobs=None, pre_dispatch='2*n_jobs', random_state=42,\n",
       "           shuffle=True, store_train_meta_features=False, stratify=True,\n",
       "           use_clones=True, use_features_in_secondary=False,\n",
       "           use_probas=False, verbose=0)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.datasets import load_iris\n",
    "from mlxtend.classifier import StackingCVClassifier\n",
    "from mlxtend.feature_selection import ColumnSelector\n",
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "iris = load_iris()\n",
    "X = iris.data\n",
    "y = iris.target\n",
    "\n",
    "pipe1 = make_pipeline(ColumnSelector(cols=(0, 2)),\n",
    "                      LogisticRegression())\n",
    "pipe2 = make_pipeline(ColumnSelector(cols=(1, 2, 3)),\n",
    "                      LogisticRegression())\n",
    "\n",
    "sclf = StackingCVClassifier(classifiers=[pipe1, pipe2], \n",
    "                            meta_classifier=LogisticRegression(),\n",
    "                            random_state=42)\n",
    "\n",
    "sclf.fit(X, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "## StackingCVClassifier\n",
      "\n",
      "*StackingCVClassifier(classifiers, meta_classifier, use_probas=False, drop_last_proba=False, cv=2, shuffle=True, random_state=None, stratify=True, verbose=0, use_features_in_secondary=False, store_train_meta_features=False, use_clones=True, n_jobs=None, pre_dispatch='2*n_jobs')*\n",
      "\n",
      "A 'Stacking Cross-Validation' classifier for scikit-learn estimators.\n",
      "\n",
      "New in mlxtend v0.4.3\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `classifiers` : array-like, shape = [n_classifiers]\n",
      "\n",
      "    A list of classifiers.\n",
      "    Invoking the `fit` method on the `StackingCVClassifer` will fit clones\n",
      "    of these original classifiers that will\n",
      "    be stored in the class attribute `self.clfs_`.\n",
      "\n",
      "- `meta_classifier` : object\n",
      "\n",
      "    The meta-classifier to be fitted on the ensemble of\n",
      "    classifiers\n",
      "\n",
      "- `use_probas` : bool (default: False)\n",
      "\n",
      "    If True, trains meta-classifier based on predicted probabilities\n",
      "    instead of class labels.\n",
      "\n",
      "- `drop_last_proba` : bool (default: False)\n",
      "\n",
      "    Drops the last \"probability\" column in the feature set since if `True`,\n",
      "    because it is redundant:\n",
      "    p(y_c) = 1 - p(y_1) + p(y_2) + ... + p(y_{c-1}).\n",
      "    This can be useful for meta-classifiers that are sensitive to\n",
      "    perfectly collinear features. Only relevant if `use_probas=True.\n",
      "\n",
      "- `cv` : int, cross-validation generator or an iterable, optional (default: 2)\n",
      "\n",
      "    Determines the cross-validation splitting strategy.\n",
      "    Possible inputs for cv are:\n",
      "    - None, to use the default 2-fold cross validation,\n",
      "    - integer, to specify the number of folds in a `(Stratified)KFold`,\n",
      "    - An object to be used as a cross-validation generator.\n",
      "    - An iterable yielding train, test splits.\n",
      "    For integer/None inputs, it will use either a `KFold` or\n",
      "    `StratifiedKFold` cross validation depending the value of `stratify`\n",
      "    argument.\n",
      "\n",
      "- `shuffle` : bool (default: True)\n",
      "\n",
      "    If True,  and the `cv` argument is integer, the training data will be\n",
      "    shuffled at fitting stage prior to cross-validation. If the `cv`\n",
      "    argument is a specific cross validation technique, this argument is\n",
      "    omitted.\n",
      "\n",
      "- `random_state` : int, RandomState instance or None, optional (default: None)\n",
      "\n",
      "    Constrols the randomness of the cv splitter. Used when `cv` is\n",
      "    integer and `shuffle=True`. New in v0.16.0.\n",
      "\n",
      "- `stratify` : bool (default: True)\n",
      "\n",
      "    If True, and the `cv` argument is integer it will follow a stratified\n",
      "    K-Fold cross validation technique. If the `cv` argument is a specific\n",
      "    cross validation technique, this argument is omitted.\n",
      "\n",
      "- `verbose` : int, optional (default=0)\n",
      "\n",
      "    Controls the verbosity of the building process.\n",
      "    - `verbose=0` (default): Prints nothing\n",
      "    - `verbose=1`: Prints the number & name of the regressor being fitted\n",
      "    and which fold is currently being used for fitting\n",
      "    - `verbose=2`: Prints info about the parameters of the\n",
      "    regressor being fitted\n",
      "    - `verbose>2`: Changes `verbose` param of the underlying regressor to\n",
      "    self.verbose - 2\n",
      "\n",
      "- `use_features_in_secondary` : bool (default: False)\n",
      "\n",
      "    If True, the meta-classifier will be trained both on the predictions\n",
      "    of the original classifiers and the original dataset.\n",
      "    If False, the meta-classifier will be trained only on the predictions\n",
      "    of the original classifiers.\n",
      "\n",
      "- `store_train_meta_features` : bool (default: False)\n",
      "\n",
      "    If True, the meta-features computed from the training data used\n",
      "    for fitting the meta-classifier stored in the\n",
      "    `self.train_meta_features_` array, which can be\n",
      "    accessed after calling `fit`.\n",
      "\n",
      "- `use_clones` : bool (default: True)\n",
      "\n",
      "    Clones the classifiers for stacking classification if True (default)\n",
      "    or else uses the original ones, which will be refitted on the dataset\n",
      "    upon calling the `fit` method. Hence, if use_clones=True, the original\n",
      "    input classifiers will remain unmodified upon using the\n",
      "    StackingCVClassifier's `fit` method.\n",
      "    Setting `use_clones=False` is\n",
      "    recommended if you are working with estimators that are supporting\n",
      "    the scikit-learn fit/predict API interface but are not compatible\n",
      "    to scikit-learn's `clone` function.\n",
      "\n",
      "- `n_jobs` : int or None, optional (default=None)\n",
      "\n",
      "    The number of CPUs to use to do the computation.\n",
      "    ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.\n",
      "    ``-1`` means using all processors. See :term:`Glossary <n_jobs>`\n",
      "    for more details. New in v0.16.0.\n",
      "\n",
      "- `pre_dispatch` : int, or string, optional\n",
      "\n",
      "    Controls the number of jobs that get dispatched during parallel\n",
      "    execution. Reducing this number can be useful to avoid an\n",
      "    explosion of memory consumption when more jobs get dispatched\n",
      "    than CPUs can process. This parameter can be:\n",
      "    - None, in which case all the jobs are immediately\n",
      "    created and spawned. Use this for lightweight and\n",
      "    fast-running jobs, to avoid delays due to on-demand\n",
      "    spawning of the jobs\n",
      "    - An int, giving the exact number of total jobs that are\n",
      "    spawned\n",
      "    - A string, giving an expression as a function of n_jobs,\n",
      "    as in '2*n_jobs'\n",
      "    New in v0.16.0.\n",
      "\n",
      "**Attributes**\n",
      "\n",
      "- `clfs_` : list, shape=[n_classifiers]\n",
      "\n",
      "    Fitted classifiers (clones of the original classifiers)\n",
      "\n",
      "- `meta_clf_` : estimator\n",
      "\n",
      "    Fitted meta-classifier (clone of the original meta-estimator)\n",
      "\n",
      "- `train_meta_features` : numpy array, shape = [n_samples, n_classifiers]\n",
      "\n",
      "    meta-features for training data, where n_samples is the\n",
      "    number of samples\n",
      "    in training data and n_classifiers is the number of classfiers.\n",
      "\n",
      "**Examples**\n",
      "\n",
      "For usage examples, please see\n",
      "    [http://rasbt.github.io/mlxtend/user_guide/classifier/StackingCVClassifier/](http://rasbt.github.io/mlxtend/user_guide/classifier/StackingCVClassifier/)\n",
      "\n",
      "### Methods\n",
      "\n",
      "<hr>\n",
      "\n",
      "*fit(X, y, groups=None, sample_weight=None)*\n",
      "\n",
      "Fit ensemble classifers and the meta-classifier.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : numpy array, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "\n",
      "- `y` : numpy array, shape = [n_samples]\n",
      "\n",
      "    Target values.\n",
      "\n",
      "\n",
      "- `groups` : numpy array/None, shape = [n_samples]\n",
      "\n",
      "    The group that each sample belongs to. This is used by specific\n",
      "    folding strategies such as GroupKFold()\n",
      "\n",
      "\n",
      "- `sample_weight` : array-like, shape = [n_samples], optional\n",
      "\n",
      "    Sample weights passed as sample_weights to each regressor\n",
      "    in the regressors list as well as the meta_regressor.\n",
      "    Raises error if some regressor does not support\n",
      "    sample_weight in the fit() method.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `self` : object\n",
      "\n",
      "\n",
      "<hr>\n",
      "\n",
      "*fit_transform(X, y=None, **fit_params)*\n",
      "\n",
      "Fit to data, then transform it.\n",
      "\n",
      "Fits transformer to X and y with optional parameters fit_params\n",
      "and returns a transformed version of X.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : numpy array of shape [n_samples, n_features]\n",
      "\n",
      "    Training set.\n",
      "\n",
      "\n",
      "- `y` : numpy array of shape [n_samples]\n",
      "\n",
      "    Target values.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `X_new` : numpy array of shape [n_samples, n_features_new]\n",
      "\n",
      "    Transformed array.\n",
      "\n",
      "<hr>\n",
      "\n",
      "*get_params(deep=True)*\n",
      "\n",
      "Return estimator parameter names for GridSearch support.\n",
      "\n",
      "<hr>\n",
      "\n",
      "*predict(X)*\n",
      "\n",
      "Predict target values for X.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : numpy array, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `labels` : array-like, shape = [n_samples]\n",
      "\n",
      "    Predicted class labels.\n",
      "\n",
      "<hr>\n",
      "\n",
      "*predict_meta_features(X)*\n",
      "\n",
      "Get meta-features of test-data.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : numpy array, shape = [n_samples, n_features]\n",
      "\n",
      "    Test vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `meta-features` : numpy array, shape = [n_samples, n_classifiers]\n",
      "\n",
      "    Returns the meta-features for test data.\n",
      "\n",
      "<hr>\n",
      "\n",
      "*predict_proba(X)*\n",
      "\n",
      "Predict class probabilities for X.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : numpy array, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `proba` : array-like, shape = [n_samples, n_classes]\n",
      "\n",
      "    Probability for each class per sample.\n",
      "\n",
      "<hr>\n",
      "\n",
      "*score(X, y, sample_weight=None)*\n",
      "\n",
      "Returns the mean accuracy on the given test data and labels.\n",
      "\n",
      "In multi-label classification, this is the subset accuracy\n",
      "which is a harsh metric since you require for each sample that\n",
      "each label set be correctly predicted.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : array-like, shape = (n_samples, n_features)\n",
      "\n",
      "    Test samples.\n",
      "\n",
      "\n",
      "- `y` : array-like, shape = (n_samples) or (n_samples, n_outputs)\n",
      "\n",
      "    True labels for X.\n",
      "\n",
      "\n",
      "- `sample_weight` : array-like, shape = [n_samples], optional\n",
      "\n",
      "    Sample weights.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `score` : float\n",
      "\n",
      "    Mean accuracy of self.predict(X) wrt. y.\n",
      "\n",
      "<hr>\n",
      "\n",
      "*set_params(**params)*\n",
      "\n",
      "Set the parameters of this estimator.\n",
      "\n",
      "Valid parameter keys can be listed with ``get_params()``.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "self\n",
      "\n",
      "### Properties\n",
      "\n",
      "<hr>\n",
      "\n",
      "*named_classifiers*\n",
      "\n",
      "None\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "with open('../../api_modules/mlxtend.classifier/StackingCVClassifier.md', 'r') as f:\n",
    "    print(f.read())"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
